222. 完全二叉树的节点个数
222. 完全二叉树的节点个数
Similar Question
leading to the advanced question
Solution Tips
方案一: 递归
var countNodes = function(node) {
// 感觉就是标准的遍历, 层次遍历写过一次了, 这次写个递归的吧. 先序遍历
// 这里的前中后遍历, 就是 1 的位置不同而已
if (node === null) return 0;
else return 1 + countNodes(node.left) + countNodes(node.right);
};
方案二: 层次遍历
var countNodes = function(node) {
const queue = [node];
let count = 0;
while (queue.length > 0) {
const n = queue.pop();
if (n !== null) {
count++;
queue.push(n.right);
queue.push(n.left);
}
}
return count;
};
方案三: 利用完全二叉树的特点
计算子数的高度, 只要左右的高度相等, 就可以直接根据层数计算出节点数
但是难点在于如何避免子树的高度反复计算
所以可以反过来, 利用递归从终止条件开始的特点, 先算最底层的节点是否是满二叉树, 再回到上层就知道是不是了
但是这样的话, 就和普通的遍历一样了, 还是没有利用到完全二叉树的特点.
所以能依赖的就只有 depth 变量的传递和维护
var countNodes = function(node, leftDepth = 0, rightDepth = 0) {
// 递归从终止条件开始想
if (node === null) return 0;
// 计算左右子数的深度, 上层计算有效就跳过
if (leftDepth <= 0) {
leftDepth = 0;
let leftNode = node.left;
while (leftNode !== null) {
leftDepth++;
leftNode = leftNode.left;
}
}
if (rightDepth <= 0) {
rightDepth = 0;
let rightNode = node.right;
while (rightNode !== null) {
rightDepth++;
rightNode = rightNode.right;
}
}
if (leftDepth === rightDepth) return (2 << leftDepth) - 1;
return 1 + countNodes(node.left, leftDepth - 1, 0) + countNodes(node.right, 0, rightDepth - 1);
};